home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / edit / jwpsrc.zip / FONT.C < prev    next >
C/C++ Source or Header  |  1993-03-31  |  15KB  |  556 lines

  1. /* Copyright (C) Stephen Chung, 1991-1993.  All rights reserved. */
  2.  
  3. #include "jwp.h"
  4.  
  5. #include <math.h>
  6.  
  7.  
  8. typedef struct fontcache {
  9.     KANJIFONT *font;
  10.     int width, height;
  11.     int size, bmsize;
  12.     int far *indexes;
  13.     BYTE far *bitmaps;
  14.     long int requests, hits, usage;
  15.     struct fontcache far *next, far *prev;
  16. } FONTCACHE;
  17.  
  18. static FONTCACHE far *FontCaches;          /* Base font always the first */
  19. static BYTE far *BaseKana = NULL;
  20. static int BaseKanaSize;
  21. static long int BaseRequests = 0L, BaseHits = 0L;
  22.  
  23. static BOOL CacheEnabled = TRUE;
  24. static BYTE far *CharBitmap = NULL;
  25.  
  26. #define DEFAULTLEADING   (1.0 / 8.0)
  27. #define DEFAULTSPACING   (1.0 / 8.0)
  28. #define KANASTART        0x2421
  29. #define KANALENGTH       83
  30. #define SYSCACHELEN      300
  31. #define OTHERCACHELEN     100
  32.  
  33.  
  34.  
  35. static int AdjustBitmapWidth(int bytes)
  36. {
  37.     int bmwidth;
  38.  
  39.     if (bytes % sizeof(int)) {
  40.         bmwidth = (bytes / sizeof(int)) + 1;
  41.         bmwidth *= sizeof(int);
  42.     } else {
  43.         bmwidth = bytes;
  44.     }
  45.  
  46.     return (bmwidth);
  47. }
  48.  
  49.  
  50.  
  51. int AllignKanjiBitmap (BYTE far *buffer, BYTE far *source, int bytes, int lines)
  52. {
  53.     int i, j, m, n;
  54.     int bmwidth;
  55.  
  56.     bytes /= lines;
  57.  
  58.     bmwidth = AdjustBitmapWidth(bytes);
  59.  
  60.     if (bmwidth == bytes) {
  61.         _fmemcpy(buffer, source, bytes * lines);
  62.     } else {
  63.         for (j = 0; j < lines; j++) {
  64.             m = j * bytes;
  65.             n = j * bmwidth;
  66.  
  67.             for (i = 0; i < bmwidth; i++)
  68.                 buffer[n + i] = (i >= bytes) ? 0 : source[m + i];
  69.         }
  70.     }
  71.  
  72.     return (bmwidth * lines);
  73. }
  74.  
  75.  
  76.  
  77. int OpenFont(char *fname, KANJIFONT *f)
  78. {
  79.     int fd;
  80.     FONTHEADER fh;
  81.  
  82.     for (;;) {
  83.         fd = OpenFile(fname, &(f->of), OF_READ);
  84.         if (fd >= 0) break;
  85.         if (!RetryMessage ("Cannot open font file '%s'!", fname)) return (-1);
  86.     }
  87.  
  88.     lseek(fd, 0L, 0);
  89.     read(fd, &fh, sizeof(FONTHEADER));
  90.  
  91.     f->facename = (KANJI *) MemAlloc(NAMELEN);
  92.     kanjicpy(f->facename, fh.facename);
  93.     f->filename = (char *) MemAlloc(strlen(fname) + 5);
  94.     strcpy(f->filename, fname);
  95.  
  96.     f->width = fh.width;
  97.     f->height = fh.height;
  98.     f->bmsize = fh.charsize;
  99.     f->offset = fh.offset;
  100.     f->verticals = fh.verticals;
  101.     f->holes = fh.holes;
  102.  
  103.     f->leading = (fh.leading <= 0) ? (double) f->width * DEFAULTLEADING : fh.leading;
  104.     f->spacing = (fh.spacing <= 0) ? (double) f->height * DEFAULTSPACING : fh.spacing;
  105.  
  106.     return (fd);
  107. }
  108.  
  109.  
  110. void EnableFontCache (BOOL On)
  111. {
  112.     CacheEnabled = On;
  113.  
  114.     if (On) {
  115.         if (CharBitmap != NULL) FreeBlock(CharBitmap);
  116.         CharBitmap = NULL;
  117.     }
  118. }
  119.  
  120.  
  121.  
  122. static FONTCACHE far *CreateCache (KANJIFONT *font, int size, int bmsize)
  123. {
  124.     int i;
  125.     long int block;
  126.     FONTCACHE far *f;
  127.  
  128.     if (FontCaches == NULL) {
  129.         FontCaches = f = StructAlloc(FONTCACHE);
  130.         f->prev = f->next = NULL;
  131.     } else {
  132.         for (f = FontCaches; f->next != NULL; f = f->next);
  133.         f->next = StructAlloc(FONTCACHE);
  134.         f->next->prev = f;
  135.         f = f->next;
  136.         f->next = NULL;
  137.     }
  138.     if (f == NULL) return (NULL);
  139.  
  140.     block = (long int) size * sizeof(int);
  141.     if (block > C64K) { size = C64K / bmsize; block = (long int) size * sizeof(int); }
  142.     f->indexes = (int far *) BlockAlloc(block);
  143.  
  144.     block = (long int) size * (long int) bmsize;
  145.     if (block > C64K) { size = C64K / bmsize; block = (long int) size * (long int) bmsize; }
  146.     f->bitmaps = (BYTE far *) BlockAlloc(block);
  147.  
  148.  
  149.     f->font = font;
  150.     f->width = font->width;
  151.     f->height = font->height;
  152.     f->size = size;
  153.     f->bmsize = bmsize;
  154.     f->requests = f->hits = f->usage = 0L;
  155.  
  156.     for (i = 0; i < size; i++) f->indexes[i] = -1;
  157.     return (f);
  158. }
  159.  
  160.  
  161.  
  162. HFONT SelectAsciiFont (HDC hdc, char *facename, double ps, TEXTMETRIC *tmout)
  163. {
  164.     int size;
  165.     HFONT hfont, oldfont;
  166.     TEXTMETRIC tm;
  167.     char buffer[MAXLINELEN];
  168.  
  169.     size = (int) floor(ps * global.resolution.y / 72.0 + 0.5);
  170.     hfont = CreateFont(-size, 0, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS,
  171.                        CLIP_DEFAULT_PRECIS, PROOF_QUALITY, FF_DONTCARE, facename);
  172.  
  173.     oldfont = SelectObject(hdc, hfont);
  174.     GetTextMetrics(hdc, &tm);
  175.  
  176.     GetTextFace(hdc, MAXLINELEN, buffer);
  177.  
  178.  
  179.     if (stricmp(buffer, facename)) {
  180.         ErrorMessage(global.hwnd, "The font '%s' is not available in this size.  The font "
  181.                                   "'%s' will be used instead.", facename, buffer);
  182.     }
  183.  
  184.     SelectObject(hdc, oldfont);
  185.     if (tmout != NULL) *tmout = tm;
  186.  
  187.     return (hfont);
  188. }
  189.  
  190.  
  191.  
  192. HFONT FindMatchingScreenFont (HFONT hfont, double scale, TEXTMETRIC *tmout)
  193. {
  194.     int size;
  195.     HDC hdc;
  196.     TEXTMETRIC tm;
  197.     HFONT screenfont;
  198.     char buffer[MAXLINELEN];
  199.  
  200.     hdc = GetPrinterDC(TRUE, NULL);
  201.     if (hdc == NULL) hdc = CreateIC("DISPLAY", NULL, NULL, NULL);
  202.  
  203.     SelectObject(hdc, hfont);
  204.     GetTextMetrics(hdc, &tm);
  205.     GetTextFace(hdc, MAXLINELEN, buffer);
  206.     DeleteDC(hdc);
  207.     hdc = CreateIC("DISPLAY", NULL, NULL, NULL);
  208.  
  209.     size = (int) floor((double) (tm.tmHeight - tm.tmInternalLeading) * scale + 0.5);
  210.  
  211.     screenfont = CreateFont(-size, 0, 0, 0, tm.tmWeight,
  212.                             tm.tmItalic, tm.tmUnderlined, tm.tmStruckOut,
  213.                             tm.tmCharSet, OUT_DEFAULT_PRECIS,
  214.                             CLIP_DEFAULT_PRECIS, DRAFT_QUALITY,
  215.                             tm.tmPitchAndFamily, buffer);
  216.  
  217.     SelectObject(hdc, screenfont);
  218.     if (tmout != NULL) GetTextMetrics(hdc, tmout);
  219.     GetTextFace(hdc, MAXLINELEN, buffer);
  220.  
  221.     DeleteDC(hdc);
  222.  
  223.     return (screenfont);
  224. }
  225.  
  226.  
  227.  
  228. int InitFonts(void)
  229. {
  230.     int i, fd;
  231.     long int size, kanastart;
  232.     HFONT hfont;
  233.     BYTE charbuf[BUFSIZE];
  234.  
  235.  
  236.     /* The system font should have been opened already */
  237.  
  238.     fd = OpenFile(NULL, &(SYSFONT->of), OF_READ | OF_REOPEN);
  239.     if (fd < 0) {
  240.         ErrorMessage(global.hwnd, "Funny!  System font not opened yet!\n\n"
  241.                                      "Program will die now.");
  242.         exit(-1);
  243.     }
  244.  
  245.     /* Get the adjusted size of a bitmap */
  246.  
  247.     BaseKanaSize = AdjustBitmapWidth(SYSFONT->bmsize / SYSFONT->height) * SYSFONT->height;
  248.  
  249.     /* Create the system kana cache */
  250.  
  251.     size = (long int) KANALENGTH * BaseKanaSize;
  252.  
  253.     if (size < C64K) {
  254.         /* Allocate the kanagana font cache */
  255.         /* #210 for 169 */
  256.  
  257.         BaseKana = (BYTE far *) BlockAlloc(size);
  258.  
  259.         kanastart = Jis2Index(KANASTART, SYSFONT->holes);
  260.  
  261.         for (i = 0; i < KANALENGTH; i++, kanastart++) {
  262.             lseek(fd, kanastart * (long int) SYSFONT->bmsize + SYSFONT->offset, 0);
  263.             read(fd, charbuf, SYSFONT->bmsize);
  264.             AllignKanjiBitmap (&(BaseKana[i * BaseKanaSize]), charbuf, SYSFONT->bmsize, SYSFONT->height);
  265.         }
  266.     }
  267.  
  268.     close(fd);
  269.  
  270.     BaseRequests = BaseHits = 0L;
  271.  
  272.     /* Allocate the system font cache */
  273.  
  274.     FontCaches = NULL;
  275.  
  276.     size = (long int) SYSCACHELEN * BaseKanaSize;
  277.  
  278.     if (size > C64K) size = C64K / BaseKanaSize;
  279.     else size = SYSCACHELEN;
  280.  
  281.     FontCaches = CreateCache (SYSFONT, size, BaseKanaSize);
  282.  
  283.     hfont = CreateFont((int) -floor(DefAsciiFont.size * global.resolution.y / 72.0 + 0.5),
  284.                        0, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS,
  285.                        CLIP_DEFAULT_PRECIS, PROOF_QUALITY, FF_DONTCARE, DefAsciiFont.facename);
  286.  
  287.     DefAsciiFont.hfont =
  288.         FindMatchingScreenFont(hfont, global.dispscale / global.printscale,
  289.                                &(DefAsciiFont.textmetric));
  290.     DeleteObject(hfont);
  291.  
  292.     FontCharWidth(0, -2);       /* Load the width tables */
  293.     return (1);
  294. }
  295.  
  296.  
  297. static int FontHash (int index, int bins)
  298. {
  299.     return (index % bins);
  300. }
  301.  
  302.  
  303.  
  304. BOOL IsSmallKana(KANJI jiscode)
  305. {
  306.     BYTE hi, lo;
  307.  
  308.     hi = HIBYTE(jiscode) & 0x7f;
  309.     lo = LOBYTE(jiscode) & 0x7f;
  310.  
  311.     if (hi == 0x24 || hi == 0x25) {         /* Hiragana & Katakana */
  312.  
  313.         switch (lo) {
  314.             case 0x21: /* a */
  315.             case 0x23: /* i */
  316.             case 0x25: /* u */
  317.             case 0x27: /* e */
  318.             case 0x29: /* o */
  319.             case 0x63: /* ya */
  320.             case 0x65: /* yu */
  321.             case 0x67: /* yo */
  322.             case 0x43: /* tu */
  323.